 package mytictactoe;


import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;

import javax.swing.*;

class Memento {
	   private int state;

	   public Memento(int  stateToSave) { state = stateToSave; }
	   public int getSavedState() { return  state; }
	}

	class Originator {
	   private int state;
	   void set(int  elemento){
				state=elemento;
		}

	   public Memento saveToMemento() { 
	       return new Memento(state); 
	   }
	   public void restoreFromMemento(Memento m) {
	       state = m.getSavedState(); 
	   }

	public int getState() {
		
		return state;
	}
	}   

	class Caretaker {
	   private ArrayList<Memento> EstadosGuardados = new ArrayList<Memento>();

	   public void addMemento(Memento m) { EstadosGuardados.add(m); }
	   public Memento getMemento() { 
		   int tam= EstadosGuardados.size();
		   Memento state= EstadosGuardados.get(tam-1); 
		   EstadosGuardados.remove(tam-1);
		   return state;
		   }
	}   


public class TicTacToeV1 implements ActionListener {
	/*Instance Variables*/
	
	Caretaker caretaker = new Caretaker();
	Originator originator = new Originator();
	
	private static JFrame window = new JFrame("Tic-Tac-Toe");

	
	private JButton button1 = new JButton("");
	private JButton button2 = new JButton("");
	private JButton button3 = new JButton("");
	private JButton button4 = new JButton("");
	private JButton button5 = new JButton("");
	private JButton button6 = new JButton("");
	private JButton button7 = new JButton("");
	private JButton button8 = new JButton("");
	private JButton button9 = new JButton("");
	
	private JButton undo = new JButton("Undo");
	private String letter = "";
	
	private int elemento=0;
	
	private int count = 0;
	private boolean win = false;

	public static void visibilidad(){
		window.setVisible(true);
		
	}
	
	
	
	
	public TicTacToeV1(){
	/*Create Window*/
	window.setSize(300,300);
	window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	window.setLayout(new GridLayout(3,3));
	
	/*Add Buttons To The Window*/
	window.add(button1);
	window.add(button2);
	window.add(button3);
	window.add(button4);
	window.add(button5);
	window.add(button6);
	window.add(button7);
	window.add(button8);
	window.add(button9);
	window.add(undo);
	
	/*Add The Action Listener To The Buttons*/
	button1.addActionListener(this);
	button2.addActionListener(this);
	button3.addActionListener(this);
	button4.addActionListener(this);
	button5.addActionListener(this);
	button6.addActionListener(this);
	button7.addActionListener(this);
	button8.addActionListener(this);
	button9.addActionListener(this);
	undo.addActionListener(this);
	
	
	undo.setEnabled(false);	
	
	
	/*Make The Window Visible*/
	}
	
	void setLetter(int elem){
		if(elem==1){
			button1.setText("");
			button1.setEnabled(true);
		}
		else if(elem==2){
			button2.setText("");
			button2.setEnabled(true);
		}
		else if(elem==3){
			button3.setText("");
			button3.setEnabled(true);
			}
		else if(elem==4){
			button4.setText("");
			button4.setEnabled(true);
			}
		else if(elem==5){
			button5.setText("");
			button5.setEnabled(true);
			}
		else if(elem==6){
			button6.setText("");
			button6.setEnabled(true);
			}
		else if(elem==7){
			button7.setText("");
			button7.setEnabled(true);
			}
		else if(elem==8){
			button8.setText("");
			button8.setEnabled(true);
			}
		else if(elem==9){
			button9.setText("");
			button9.setEnabled(true);
			}
	}
	
	public void actionPerformed(ActionEvent a) {
		
		undo.setEnabled(true);
		if(a.getSource() != undo){
		 count++;
		}
		/*Calculate Who's Turn It Is*/
		if(count == 1 || count == 3 || count == 5 || count == 7 || count == 9){
		letter = "X";
		
		
		
		} else if(count == 2 || count == 4 || count == 6 || count == 8 || count == 10){
		letter = "O";

		}
		
		/*Display X's or O's on the buttons*/
		if(a.getSource() == button1){
			button1.setText(letter);
			originator.set(1);
			caretaker.addMemento( originator.saveToMemento() );
			button1.setEnabled(false);
		} else if(a.getSource() == button2){
			button2.setText(letter);
			originator.set(2);
			caretaker.addMemento( originator.saveToMemento() );
			button2.setEnabled(false);
		} else if(a.getSource() == button3){
			button3.setText(letter);
			originator.set(3);
			caretaker.addMemento( originator.saveToMemento() );
			button3.setEnabled(false);
		} else if(a.getSource() == button4){
			button4.setText(letter);
			originator.set(4);
			caretaker.addMemento( originator.saveToMemento() );
			button4.setEnabled(false);
		} else if(a.getSource() == button5){
			button5.setText(letter);
			originator.set(5);
			caretaker.addMemento( originator.saveToMemento() );
			button5.setEnabled(false);
		} else if(a.getSource() == button6){
			button6.setText(letter);
			originator.set(6);
			caretaker.addMemento( originator.saveToMemento() );
			button6.setEnabled(false);
		} else if(a.getSource() == button7){
			button7.setText(letter);
			originator.set(7);
			caretaker.addMemento( originator.saveToMemento() );
			button7.setEnabled(false);
		} else if(a.getSource() == button8){
			button8.setText(letter);
			originator.set(8);
			caretaker.addMemento( originator.saveToMemento() );
			button8.setEnabled(false);
		} else if(a.getSource() == button9){
			button9.setText(letter);
			originator.set(9);
			caretaker.addMemento( originator.saveToMemento() );
			button9.setEnabled(false);
		}
		 else if(a.getSource() == undo){
			 System.out.println("antes "+count);
			 count--;
			 System.out.println("despues "+count);
			 originator.restoreFromMemento( caretaker.getMemento() );
			 int elem=originator.getState();
			 setLetter(elem);
			 if(count==0){
				 undo.setEnabled(false);
				 
			 }
			}
		
		/*Determine who won*/
		//horizontal wins
		if( button1.getText() == button2.getText() && button2.getText() == button3.getText() && button1.getText() != ""){
			win = true;
		}
		else if(button4.getText() == button5.getText() && button5.getText() == button6.getText() && button4.getText() != ""){
			win = true;
		}
		else if(button7.getText() == button8.getText() && button8.getText() == button9.getText() && button7.getText() != ""){
			win = true;
		}
		
		//virticle wins
		else if(button1.getText() == button4.getText() && button4.getText() == button7.getText() && button1.getText() != ""){
			win = true;
		}
		else if(button2.getText() == button5.getText() && button5.getText() == button8.getText() && button2.getText() != ""){
			win = true;
		}
		else if(button3.getText() == button6.getText() && button6.getText() == button9.getText() && button3.getText() != ""){
			win = true;
		}
		
		//diagonal wins
		else if(button1.getText() == button5.getText() && button5.getText() == button9.getText() && button1.getText() != ""){
			win = true;
		}
		else if(button3.getText() == button5.getText() && button5.getText() == button7.getText() && button3.getText() != ""){
			win = true;
		}
		else {
			win = false;
		}
		
		
		/*Show a dialog if someone wins or the game is tie*/
		if(win == true){
			JOptionPane.showMessageDialog(null, letter + " WINS!");
		} else if(count == 9 && win == false){
			JOptionPane.showMessageDialog(null, "Tie Game!");
		}
	}
	
}